package br.ufrn.sipac.patrimonio.coletor.integrationTest;

import java.util.Collection;

import android.test.ActivityInstrumentationTestCase2;
import br.ufrn.sipac.patrimonio.coletor.activity.AutenticacaoActivity;
import br.ufrn.sipac.patrimonio.coletor.controller.DatabaseController;
import br.ufrn.sipac.patrimonio.coletor.controller.MainController;
import br.ufrn.sipac.patrimonio.coletor.dominio.FinalidadeLevantamento;
import br.ufrn.sipac.patrimonio.coletor.dominio.Localidade;
import br.ufrn.sipac.patrimonio.coletor.dominio.Unidade;
import br.ufrn.sipac.patrimonio.coletor.dominio.UsuarioColetor;
import br.ufrn.sipac.patrimonio.coletor.exception.DatabaseException;
import br.ufrn.sipac.patrimonio.coletor.exception.NegocioException;
import br.ufrn.sipac.patrimonio.coletor.exception.TransmissaoException;
import br.ufrn.sipac.patrimonio.coletor.transmissao.GenericSOAP;

/**
 * Esse caso de teste de integração testa a consistência dos dados remotos
 * localmente com base na estratégia de consistência definida. Logo após uma
 * chamada a umm método remoto é verificado se os dados consultados são
 * persistidos localmente.
 * 
 * @author Giuliana Silva Bezerra
 * 
 */
public class ConsistenciaIntegrationTest extends
		ActivityInstrumentationTestCase2<AutenticacaoActivity> {

	private AutenticacaoActivity context;

	public ConsistenciaIntegrationTest() {
		super(AutenticacaoActivity.class);
	}

	public ConsistenciaIntegrationTest(String name) {
		super(AutenticacaoActivity.class);
		setName(name);
	}

	protected void setUp() throws Exception {
		super.setUp();
		context = getActivity();
	}

	protected void tearDown() throws Exception {
		super.tearDown();
	}

	public final void testPreconditions() {
		assertNotNull(context);
	}

	/**
	 * Verifica a consistência dos dados carregados durante a operação de login
	 * no sistema.
	 * 
	 * @throws TransmissaoException
	 * @throws DatabaseException
	 */
	public void testLogar() throws TransmissaoException, DatabaseException {
		// Usuário que existe no SIPAC.
		MainController.setLogin("admin");
		MainController.setSenha("123456");
		MainController.logar(context);

		GenericSOAP soap = new GenericSOAP();
		UsuarioColetor userDTO = soap.capturarUsuario(
				MainController.getLogin(), context);

		// Usuário persistido de forma consistente.
		UsuarioColetor userLocal = (UsuarioColetor) DatabaseController
				.findUsuarioById(context, userDTO.getId());
		assertEquals(userDTO.getLogin(), userLocal.getLogin());
		assertEquals(userDTO.getUnidade().getId(), userLocal.getUnidade()
				.getId());
		assertEquals(userDTO.getId(), userLocal.getId());

		// Unidades persistidas de forma consistente
		MainController.findUnidadesPermissao(context);
		for (Unidade unidadeDTO : MainController.unidadesPermitidas) {
			Unidade unidLocal = (Unidade) DatabaseController.findUnidadeById(
					context, unidadeDTO.getId());
			assertEquals(unidLocal.getCodigoUnidade(),
					unidadeDTO.getCodigoUnidade());
			assertEquals(unidLocal.getId(), unidadeDTO.getId());
			assertEquals(unidLocal.getSigla(), unidadeDTO.getSigla());
		}
	}

	/**
	 * Verifica a consistência dos dados carregados durante o carregamento de
	 * finalidades de levantamento no sistema.
	 * 
	 * @throws DatabaseException
	 * @throws TransmissaoException
	 */
	public void testFindFinalidadesLevantamento() throws DatabaseException,
			TransmissaoException {
		Collection<FinalidadeLevantamento> finalidades = MainController
				.findFinalidadesLevantamento(context);

		for (FinalidadeLevantamento finalidadeDTO : finalidades) {
			FinalidadeLevantamento finalidadeLocal = (FinalidadeLevantamento) DatabaseController
					.findFinalidadeById(context, finalidadeDTO.getId());
			assertEquals(finalidadeDTO.getDenominacao(),
					finalidadeLocal.getDenominacao());
			assertEquals(finalidadeDTO.getId(), finalidadeLocal.getId());
		}
	}

	/**
	 * Verifica a consistência dos dados carregados durante o carregamento de
	 * localidades no sistema.
	 * 
	 * @throws NegocioException
	 * @throws DatabaseException
	 * @throws TransmissaoException
	 */
	public void testFindLocaisByUnidade() throws NegocioException,
			DatabaseException, TransmissaoException {
		MainController.findUnidadesPermissao(context);

		for (Unidade unidade : MainController.unidadesPermitidas) {
			Collection<Localidade> locais = MainController.findLocaisByUnidade(
					context, unidade.getId(), unidade.getCodigoUnidade());

			for (Localidade localidadeDTO : locais) {
				Localidade localidadeLocal = (Localidade) DatabaseController
						.findLocalidadeById(context, localidadeDTO.getId());
				assertEquals(localidadeDTO.getCodigo(),
						localidadeLocal.getCodigo());
				assertEquals(localidadeDTO.getDenominacao(),
						localidadeLocal.getDenominacao());
				assertEquals(localidadeDTO.getId(), localidadeLocal.getId());
				assertEquals(localidadeDTO.getNomeCompleto(),
						localidadeLocal.getNomeCompleto());
				assertEquals(localidadeDTO.getUnidade().getId(),
						localidadeLocal.getUnidade().getId());
			}
		}
	}
}
